Analysis of binary executable programs is performed to analyze program performance, verify correctness, and test correct runtime operation, for example. Some analyses are performed prior to runtime (static analysis), while other analyses are performed during runtime (dynamic analysis). For both static and dynamic analysis, however, the analysis is often performed at the function level.
The term, “function”, refers to named sections of code that are callable in the source program and encompasses routines, procedures, methods and other similar constructs known to those skilled in the art. The functions in the source code are compiled into segments of executable code. For convenience, the segments of executable code that correspond to the functions in the source code are also referred to as “functions”.
A function is a set of instructions beginning at an entry point and ending at an endpoint. The entry point is the address at which execution of the function begins as the target of a branch instruction. The endpoint is the instruction of the function from which control is returned to the point in the program at which the function was initiated. For functions having multiple entry points and/or multiple endpoints, the first entry point and the last endpoint define a function.
One category of analysis performed on executable programs is “instrumentation”. Instrumentation is generally used to gather runtime characteristics of a program. For example, the number of times that a function is executed while the application is executing is determined through instrumentation. While the information gathered through instrumentation may be extremely useful for purposes of enhancing program performance, the process of setting up a program for instrumentation can be time-consuming.
Some dynamic instrumentation tools relocate instrumented functions into a shared memory address space during execution of the program. The shared memory space is allocated by the instrumentation tool and shared by the instrumentation tool and the executable program. The instrumented functions in the shared memory space are executed in lieu of the un-instrumented versions of the functions in the original address space. Some instrumented functions in the shared memory space may call other instrumented functions in the shared memory space, depending on the application.
Where one function (“caller” or “calling” function) calls another function (“called function”), a return pointer (RP) register is used in some computer architectures for some functions to return control from the called function to the calling function. For example, Hewlett Packard's IA-64 instruction architecture uses a return pointer register.
Some functions require that the value in the return pointer register reference an address within the original address space. For example, the function may use the return pointer value for comparison and expect the value to be in the original address space. If the return pointer value is an address within the shared memory space, the program will abort because of a memory reference that is out of a recognized range.
A method and apparatus that address the aforementioned problems, as well as other related problems, are therefore desirable.